package com.nbwyctf.helper.exception;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.nbwyctf.helper.enums.ErrorCode;
import com.nbwyctf.helper.result.AjaxResult;

/**
 * @author chetaifu
 */
public class BusinessException extends RuntimeException{
    private final int errorCode;
    private final String message;
    private final Object data;


    public BusinessException(ErrorCode code) {
        this(code.getCode(), code.getMessage(), null);
    }

    public BusinessException(ErrorCode code, String msg) {
        this(code.getCode(), msg, null);
    }

    public BusinessException(ErrorCode code, Object payload) {
        this(code.getCode(), code.getMessage(), payload);
    }

    public BusinessException(int errorCode, String errorMessage) {
        this(errorCode, errorMessage, null);
    }

    /**
     * 创建一个业务异常实例
     */
    @JsonCreator
    public BusinessException(
            @JsonProperty("errorCode") int errorCode,
            @JsonProperty("errorMessage") String message,
            @JsonProperty("payload") Object data) {
        super(String.format("[%s] %s", errorCode, data));
        this.errorCode = errorCode;
        this.message = message;
        this.data = data;
    }

    /**
     * 根据指定的错误消息派生出一个新的 BusinessException 的实例。
     * 新的实例具有和当前实例相同的 errorCode 和 data。
     */
    public BusinessException derive(String alternativeErrorMessage) {
        return new BusinessException(errorCode, alternativeErrorMessage, data);
    }

    /**
     * 根据指定的错误负载派生出一个新的 BusinessException 的实例。
     * 新的实例具有和当前实例相同的 errorCode 和 message。
     */
    public BusinessException derive(Object alternativePayload) {
        return new BusinessException(errorCode, message, alternativePayload);
    }

    /**
     * 根据指定的错误消息和负载派生出一个新的 BusinessException 的实例。
     * 新的实例具有和当前实例相同的 errorCode。
     */
    public BusinessException derive(String alternativeErrorMessage, Object alternativePayload) {
        return new BusinessException(errorCode, alternativeErrorMessage, alternativePayload);
    }

    public AjaxResult toApiResult() {
        return AjaxResult.ajaxFailed(message);
    }

    public int getErrorCode() {
        return errorCode;
    }

    public String getMessage() {
        return message;
    }

    public Object getData() {
        return data;
    }
}
